package com.atguigu.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.base.BaseDAO;
import com.atguigu.base.BaseServiceImpl;
import com.atguigu.dao.AdminRoleDAO;
import com.atguigu.dao.RoleDAO;
import com.atguigu.entity.AdminRole;
import com.atguigu.entity.Role;
import com.atguigu.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @PACKAGE_NAME: com.atguigu.service.impl
 * @CLASSNAME: RoleServiceImpl
 * @AUTHOR: zhangsan
 * @DATE: 2024/4/14 18:16
 * @SINCE 17.0.7
 * @DESCRIPTION: RoleServiceImpl
 */
@Slf4j
@Service(interfaceClass = RoleService.class)
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class RoleServiceImpl extends BaseServiceImpl<Role> implements RoleService {
    @Resource
    private RoleDAO roleDAO;

    @Resource
    private AdminRoleDAO adminRoleDAO;

    @Override
    protected BaseDAO<Role> getEntityDAO() {
        return roleDAO;
    }

    @Override
    public List<Role> findAll() {
        List<Role> roles = roleDAO.findAll();
        return roles;
    }

    /**
     * 通过用户id查找该用户的角色信息
     * ${adminId} ${noAssignRoleList} ${assignRoleList}
     * ${item.id} ${item.roleName}
     * 前端需要的信息,也就是map的key
     *
     * @param adminId
     * @return
     */
    @Override
    public Map<String, Object> findRoleByAdminId(Long adminId) {
        //todo 写该方法
        List<Role> allRoles = roleDAO.findAll();
        //List<Long> allRoleIds = allRoles.stream().map(Role::getId).collect(Collectors.toList());
        //已经分配给该角色的权限
        List<Long> assignRoleIds = adminRoleDAO.findRoleIdsByAdminId(adminId, 0);
        List<Role> assignRoleList = new ArrayList<>();
        assignRoleIds.forEach(roleId -> {
            Role assignRole = roleDAO.getById(roleId);
            assignRoleList.add(assignRole);
        });
        //if (assignRoleIds.contains(role.getId())) {
        //    return false;
        //} else {
        //    return true;
        //}
        List<Role> noAssignRoleList = allRoles.stream().filter(role -> !(assignRoleIds.contains(role.getId()))).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("noAssignRoleList", noAssignRoleList);
        map.put("assignRoleList", assignRoleList);
        return map;
    }

    /**
     * 给用户分配角色
     *
     * @param adminId 分配角色的用户id
     * @param roleIds 要分配的角色,可以为空,就不给分配角色
     * @return
     */
    @Override
    public void assignRolesToAdmin(Long adminId, Long[] roleIds) {
        //注意roleIds可以为null,就是不给他分配任何角色,或者说取消他已经分配了的角色
        //所以老师的代码才有deleteByAdminId,上来先删除该用户持有的所有角色,接着利用
        //roleIds给重新分配
        //上来先将之前分配给该用户的所有角色清空,给重新分配
        AdminRole adminRole = new AdminRole();
        adminRole.setAdminId(adminId);
        adminRole.setIsDeleted(1);
        Integer i = adminRoleDAO.updateIsDeletedByRoleIdAndAdminId(adminRole);
        log.debug("i = {}", i);

        //查询该用户之前拥有的角色(不论is_deleted的值)
        List<Long> assignedRoleIdsWithoutIsDeleted = adminRoleDAO.findRoleIdsByAdminId(adminId, null);

        if (null == roleIds || roleIds.length == 0) {
            //说明没有给他分配任何角色,直接返回,因为已经将之前分配给该用户的所有角色清空
            return;
        }

        Map<Boolean, List<Long>> collect = Arrays.stream(roleIds).collect(Collectors.partitioningBy(assignedRoleIdsWithoutIsDeleted::contains));
        //包含的为true,不包含的为false
        List<Long> existedRoleIds = collect.get(true);
        List<Long> noExistedRoleIds = collect.get(false);
        existedRoleIds.forEach(roleId -> {
            AdminRole adminRole1 = new AdminRole();
            adminRole1.setRoleId(roleId);
            adminRole1.setAdminId(adminId);
            adminRole1.setIsDeleted(0);
            Integer i1 = adminRoleDAO.updateIsDeletedByRoleIdAndAdminId(adminRole1);
            log.debug("i1 = {}", i1);
        });

        noExistedRoleIds.forEach(roleId -> {
            AdminRole adminRole2 = new AdminRole();
            adminRole2.setId(null);
            adminRole2.setAdminId(adminId);
            adminRole2.setRoleId(roleId);
            Integer i1 = adminRoleDAO.insert(adminRole2);
            log.debug("inserti1 = {}", i1);
        });
    }

    /**
     * 通过id查到用户的角色信息
     *
     * @param adminId
     * @return
     */
    @Override
    public List<Role> findRolesByAdminId(Long adminId) {
        List<Long> assignRoleIds = adminRoleDAO.findRoleIdsByAdminId(adminId, 0);
        List<Role> assignRoleList = new ArrayList<>();
        assignRoleIds.forEach(roleId -> {
            Role assignRole = roleDAO.getById(roleId);
            assignRoleList.add(assignRole);
        });
        return assignRoleList;
    }
}
